package dosgi.distribution;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Map;

public class RemoteInvocationArguments implements Serializable {

	private static final long serialVersionUID = 1382231166286519677L;
	
	private String className;
	private String methodName;
	private Map<Class<?>, Object> args;
	private Map<String, String> properties;
	
	public RemoteInvocationArguments() {}
	
	public RemoteInvocationArguments(String className, String methodName, Map<Class<?>, Object> args, Map<String, String> properties) {
		this.className = className;
		this.methodName = methodName;
		this.args = args;
		this.properties = properties;
	}
	
	public String getClassName() {
		return className;
	}
	
	@Deprecated
	public void setClassName(String className) {
		this.className = className;
	}
	public String getMethodName() {
		return methodName;
	}
	
	@Deprecated
	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}
	public Map<Class<?>, Object> getArgs() {
		return args;
	}
	
	@Deprecated
	public void setArgs(Map<Class<?>, Object> args) {
		this.args = args;
	}
	public Map<String, String> getProperties() {
		return properties;
	}
	
	@Deprecated
	public void setProperties(Map<String, String> properties) {
		this.properties = properties;
	}

	public static byte[] toByteArray(RemoteInvocationArguments args) throws IOException {
		ObjectOutput out;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		out = new ObjectOutputStream(bos);
		out.writeObject(args);
		out.close();
		
		return bos.toByteArray();
	}
	
	public byte[] toByteArray() throws IOException {
		ObjectOutput out;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		out = new ObjectOutputStream(bos);
		out.writeObject(this);
		out.close();
		
		return bos.toByteArray();
	}
	
	public static RemoteInvocationArguments getFromByteArray(byte[] bytes) throws IOException, ClassNotFoundException {
		ObjectInput in;
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		in = new ObjectInputStream(bais);
		Object res = in.readObject();
		
		if (res instanceof RemoteInvocationArguments) {
			return (RemoteInvocationArguments) res;
		} else {
			throw new IOException("Wrong message format");
		}
	}
	
	public static final class Builder {
		private String className;
		private String methodName;
		private Map<Class<?>, Object> args;
		private Map<String, String> properties;

		public Builder() {
		};

		public Builder className(String className) {
			this.className = className;
			return this;
		}
		
		public Builder methodName(String methodName) {
			this.methodName = methodName;
			return this;
		}
		
		public Builder arguments(Map<Class<?>, Object> args) {
			this.args = args;
			return this;
		}
		
		public Builder properties(Map<String, String> props) {
			this.properties = props;
			return this;
		}

		public RemoteInvocationArguments build() {
			return new RemoteInvocationArguments(className, methodName, args, properties);
		}
	}
	
}
